package com.linq.cool.auth.controller;

import com.alibaba.fastjson.JSON;
import com.anji.captcha.model.common.ResponseModel;
import com.anji.captcha.service.CaptchaService;
import com.linq.cool.api.domain.BeautyMember;
import com.linq.cool.api.dto.BeautyMemberBindDTO;
import com.linq.cool.api.dto.BeautyMemeberRegisterDTO;
import com.linq.cool.api.feign.RemoteBeautyMemberService;
import com.linq.cool.api.feign.RemoteSysUserService;
import com.linq.cool.api.vo.LoginUser;
import com.linq.cool.api.vo.WeChatLoginUser;
import com.linq.cool.api.vo.WebLoginUser;
import com.linq.cool.auth.config.WeChatProperties;
import com.linq.cool.auth.dto.BeautyMemberLoginDTO;
import com.linq.cool.auth.dto.LoginBodyDTO;
import com.linq.cool.auth.dto.WeChatRegisterDTO;
import com.linq.cool.auth.dto.WxLoginDTO;
import com.linq.cool.auth.service.SysLoginService;
import com.linq.cool.auth.vo.WeChatResult;
import com.linq.cool.common.constants.CacheConstants;
import com.linq.cool.common.constants.Constants;
import com.linq.cool.common.constants.UserConstants;
import com.linq.cool.common.core.domain.Result;
import com.linq.cool.common.core.utils.*;
import com.linq.cool.common.redis.service.RedisService;
import com.linq.cool.common.security.service.SysTokenService;
import com.linq.cool.common.security.service.WeChatTokenService;
import com.linq.cool.common.security.service.WebTokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: yqlin
 * @Date: 2021/1/3 02:01
 * @Description: token控制
 * @Version: 1.0.0
 */
@RestController
public class AuthController {
    @Value("${test}")
    private String test;
    @Autowired
    private SysTokenService sysTokenService;
    @Autowired
    private WeChatTokenService weChatTokenService;
    @Autowired
    private WebTokenService webTokenService;
    @Autowired
    private SysLoginService sysLoginService;
    @Autowired
    private CaptchaService captchaService;
    @Autowired
    private RemoteSysUserService remoteSysUserService;
    @Autowired
    private RemoteBeautyMemberService remoteBeautyMemberService;
    @Autowired
    private WeChatProperties weChatConfig;
    @Autowired
    private RedisService redisService;

    /**
     * 图片验证码登录
     *
     * @param dto 前台登录对象
     *
     * @return 结果
     */
    @PostMapping("member/login")
    public Result<?> memberLogin(@RequestBody BeautyMemberLoginDTO dto) {
        // 用户登录
        WebLoginUser userInfo = sysLoginService.doWebLogin(dto.getPhone(), dto.getPassword());
        // 获取登录token
        return Result.ok(webTokenService.createToken(userInfo));
    }

    /**
     * 前台注册
     *
     * @param dto
     *
     * @return
     */
    @PostMapping("member/register")
    public Result<?> memberRegister(@Validated @RequestBody BeautyMemeberRegisterDTO dto) {
        Result<?> result = remoteBeautyMemberService.frontRegister(dto);
        if (Result.FAIL.equals(result.getCode())) {
            return Result.fail(result.getMessage());
        }
        return Result.ok("注册成功");
    }

    /**
     * 前台客户退出
     *
     * @param request
     *
     * @return
     */
    @DeleteMapping("member/logout")
    public Result<?> memberLogout(HttpServletRequest request) {
        WebLoginUser loginUser = webTokenService.getLoginUser(request);
        if (StringUtils.isNotNull(loginUser)) {
            // 删除用户缓存记录
            webTokenService.removeLoginUser(loginUser.getToken());
        }
        return Result.ok();
    }

    /**
     * 系统滑块验证码登录
     *
     * @param dto 用户登录对象
     *
     * @return 结果
     */
    @PostMapping("login/slide")
    public Result<?> loginSlide(@RequestBody LoginBodyDTO dto) {
        ResponseModel response = captchaService.verification(dto.getCaptchaVO());
        if (response.isSuccess()) {
            // 用户登录
            LoginUser userInfo = sysLoginService.doLogin(dto.getUsername(), dto.getPassword());
            return Result.ok(sysTokenService.createToken(userInfo));
        }
        Map<String, Object> map = new HashMap<>(2);
        map.put("repCode", response.getRepCode());
        return Result.fail(map);
    }

    @DeleteMapping("logout")
    public Result<?> logout(HttpServletRequest request) {
        LoginUser loginUser = sysTokenService.getLoginUser(request);
        if (StringUtils.isNotNull(loginUser)) {
            String username = loginUser.getUsername();
            // 删除用户缓存记录
            sysTokenService.removeLoginUser(loginUser.getToken());
            // 记录用户退出日志
            sysLoginService.logout(username);
        }
        return Result.ok();
    }

    @PostMapping("refresh")
    public Result<?> refresh(HttpServletRequest request) {
        LoginUser loginUser = sysTokenService.getLoginUser(request);
        if (StringUtils.isNotNull(loginUser)) {
            // 刷新令牌有效期
            sysTokenService.refreshToken(loginUser);
            return Result.ok();
        }
        return Result.ok();
    }


    /**
     * 微信登录
     *
     * @return
     */
    @GetMapping("wxLogin")
    public Result<?> wxLogin(@RequestBody WxLoginDTO dto) throws IOException {
        // 发送请求到微信服务器
        String loginBody = HttpUtils.get(weChatConfig.getAuthUrl(dto.getCode())).body();
        // 转换成WeChatResult
        WeChatResult weChatResult = JSON.parseObject(loginBody, WeChatResult.class);
        Result<WeChatLoginUser> memberResult = remoteBeautyMemberService.getMemberInfo(weChatResult.getOpenId());
        WeChatLoginUser loginUser = memberResult.getData();
        if (null == loginUser) {
            return Result.ok(weChatResult, "用户不存在");
        }
        if (StringUtils.isBlank(loginUser.getPhone())) {
            return Result.ok(weChatResult, "请先绑定手机号");
        }
        // 判断当前redis中是否存在此token如果存在就返回当前存在的token然后刷新token过期时间
        Result<?> token = this.getCurrentWxLoginUser(weChatResult);
        if (token != null) {
            return token;
        }
        loginUser.setOpenId(weChatResult.getOpenId());
        return Result.ok(weChatTokenService.createToken(loginUser));
    }

    /**
     * 注册登录
     *
     * @param dto
     *
     * @return
     */
    @PostMapping("wxRegisterLogin")
    public Result<?> wxRegisterLogin(@RequestBody WeChatRegisterDTO dto) {
        Result<WeChatLoginUser> weChatResult = remoteBeautyMemberService.getMemberInfo(dto.getOpenId());
        if (null == weChatResult.getData()) {
            Result<?> registerResult = remoteBeautyMemberService.wxRegister(dto.toBeautyMember());
            if (Result.FAIL.equals(registerResult.getCode())) {
                return Result.fail(registerResult.getMessage());
            }
        }
        Result<WeChatLoginUser> memberResult = remoteBeautyMemberService.getMemberInfo(dto.getOpenId());
        if (null == memberResult.getData()) {
            return Result.ok(weChatResult, "用户不存在");
        }
        WeChatLoginUser loginUser = memberResult.getData();
        loginUser.setOpenId(dto.getOpenId());
        return Result.ok(weChatTokenService.createToken(loginUser));
    }

    /**
     * 绑定客户账号
     *
     * @param dto
     *
     * @return
     */
    @PostMapping("wxbindMember")
    public Result<?> wxLoginBindMember(@Validated @RequestBody BeautyMemberBindDTO dto) {
        if (!RegexUtils.checkMobile(dto.getPhone())) {
            return Result.fail("手机号不合法");
        }
        Result<BeautyMember> result = remoteBeautyMemberService.bindMember(dto);
        if (result.getData() == null) {
            return Result.fail(result.getMessage());
        }
        BeautyMember member = result.getData();
        return Result.ok(weChatTokenService.createToken(member.toWeChatLoginUser()), "绑定成功");
    }

    @GetMapping("getWxLoginInfo")
    public Result<?> getWxLoginInfo() {
        return Result.ok(weChatTokenService.getLoginUser());
    }

    private Result<?> getCurrentWxLoginUser(WeChatResult weChatResult) {
        Collection<String> keys = redisService.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
        for (String key : keys) {
            String token = key.replace(CacheConstants.LOGIN_TOKEN_KEY, "");
            Integer loginType = JwtUtils.getLoginType(token);
            if (UserConstants.StateEnum.LOGIN_TYPE_WECHAT.getCode().equals(loginType)) {
                WeChatLoginUser user = redisService.getCacheObject(key);
                if (user.getOpenId().equals(weChatResult.getOpenId())) {
                    weChatTokenService.refreshToken(user);
                    Map<String, Object> map = new HashMap<>(2);
                    map.put("access_token", token);
                    map.put("expires_in", Constants.TOKEN_EXPIRE * 60);
                    return Result.ok(map);
                }
            }
        }
        return null;
    }


    @GetMapping("test")
    public Result<?> test() {
        return remoteSysUserService.getUserInfo("admin");
    }

    @GetMapping("test/message")
    public Result<?> testMessage() {
        return Result.ok(MessageUtils.message("user.not.exists"));
    }
}
